package com.splic.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.splic.common.config.BaiduConfig;
import com.splic.common.config.QQConfig;
import com.splic.common.core.DeviceContext;
import com.splic.common.core.redis.RedisCache;
import com.splic.common.enums.ThirdUserTypeEnum;
import com.splic.common.exception.BusinessException;
import com.splic.common.utils.JwtUtils;
import com.splic.common.utils.StringUtils;
import com.splic.common.utils.security.Md5Utils;
import com.splic.product.domain.Product;
import com.splic.product.domain.User;
import com.splic.product.domain.UserThirdBind;
import com.splic.product.dto.ThirdLoginDto;
import com.splic.product.mapper.UserThirdBindMapper;
import com.splic.product.service.ProductService;
import com.splic.product.service.ThirdLoginService;
import com.splic.product.service.UserService;
import com.splic.product.service.UserThirdBindService;
import com.splic.product.service.impl.pay.AlipayPayService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpOAuth2ServiceImpl;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ==========================
 * 开发：singe
 * 创建时间：2022-03-10 22:39
 * 版本: 1.0
 * 描述：微信登录相关接口
 * ==========================
 */
@Service
@Slf4j
public class ThirdLoginServiceImpl implements ThirdLoginService {

    @Autowired
    private ProductService productServiceImpl;
    @Autowired
    private UserService userServiceImpl;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserThirdBindService userThirdBindServiceImpl;
    @Autowired
    private AlipayPayService alipayPayServiceImpl;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserThirdBindMapper userThirdBindMapper;

    public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
        WxOAuth2AccessToken accessToken = getWxOAuth2Service().getAccessToken(code);
        return accessToken;
    }

    public WxOAuth2AccessToken refreshToken(String accessToken) throws WxErrorException {
        WxOAuth2AccessToken authAccessToken = getWxOAuth2Service().refreshAccessToken(accessToken);
        return authAccessToken;
    }

    public WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken accessToken) throws WxErrorException {
        WxOAuth2UserInfo userInfo = getWxOAuth2Service().getUserInfo(accessToken,null);
        return userInfo;
    }

    public WxOAuth2Service getWxOAuth2Service(){
        Product product = productServiceImpl.getByPackageKey(DeviceContext.getProductPackageKey());
        if (product == null){
            throw new BusinessException("应用获取失败");
        }

        JSONObject jsonObject = JSONObject.parseObject(product.getWechatConfig());

        WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
        wxMpConfigStorage.setAppId(jsonObject.getString("appId"));
        wxMpConfigStorage.setSecret(jsonObject.getString("secret"));

        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage);

        WxMpOAuth2ServiceImpl auth2Service = new WxMpOAuth2ServiceImpl(wxMpService);

        return auth2Service;
    }


    /**
     * 微信快速登录
     *
     * @param code
     * @param isMerge
     * @return
     */
    @Override
    public User thirdQuickLogin(String code, String thirdType, String thirdUserId, Integer isMerge)  {
        if (isMerge == 1) {
            User aliUser = redisCache.getCacheObject(thirdUserId);
            User origin = userServiceImpl.getByAccount(aliUser.getAccount());
            if (origin != null) {
                UserThirdBind userThirdBindAli = userThirdBindServiceImpl.getByTypeAndUserId(origin.getId(), "alipay");
                userThirdBindMapper.deleteLogoutThirdBindById(userThirdBindAli.getId());
                userThirdBindMapper.insertLogOutBackUp(userThirdBindAli);
                userThirdBindAli = new UserThirdBind();
                userThirdBindAli.setType("alipay");
                userThirdBindAli.setValue(thirdUserId);
                userThirdBindAli.setUserId(origin.getId());
                userThirdBindMapper.insert(userThirdBindAli);
                if (StringUtils.isEmpty(origin.getHeadImg())) {
                    origin.setHeadImg(aliUser.getHeadImg());
                }
                if (StringUtils.isEmpty(origin.getNickname())) {
                    origin.setNickname(aliUser.getNickname());
                }
                if (origin.getSex() == null || origin.getSex() == 0) {
                    origin.setSex(aliUser.getSex());
                }
                origin.setAccountCheck(1);
                userServiceImpl.update(origin);
            }
            return origin;
        } else if (isMerge == 0) {
            User aliUser = redisCache.getCacheObject(thirdUserId);
            aliUser.setAccount("");
            aliUser.setAccountCheck(0);
            aliUser.setRegisterTime(new Date());
            aliUser.setPassword(Md5Utils.hash("ej123456"));
            userServiceImpl.insert(aliUser);
            UserThirdBind temp = new UserThirdBind();
            temp.setType("alipay");
            temp.setValue(thirdUserId);
            temp.setUserId(aliUser.getId());
            userThirdBindServiceImpl.insert(temp);
            aliUser.setThirdUserId(thirdUserId);
            aliUser.setThirdUserType("alipay");
            return aliUser;
        }

        ThirdUserTypeEnum thirdUserTypeEnum = ThirdUserTypeEnum.valueOf(thirdType);
        if (thirdUserTypeEnum == null){
            throw new BusinessException("三方登录类型错误。");
        }

        String accessToken = "";
        User user = null;
        AlipayUserInfoShareResponse userInfoShareResponse = null;
        try {
            if (StringUtils.equals(ThirdUserTypeEnum.wechat.name(),thirdUserTypeEnum.name())){
                thirdUserId = wxQuery(code).getUnionId();
            }else if(StringUtils.equals(ThirdUserTypeEnum.alipay.name(),thirdUserTypeEnum.name())){
                JSONObject resultJson = aliQuery(code);
                if (resultJson != null) {
                    thirdUserId = resultJson.getString("userId");
                    accessToken = resultJson.getString("accessToken");
                    userInfoShareResponse = getUserInfo(accessToken, 0);
                    if (userInfoShareResponse != null) {
                        User aliUser = new User();
                        if (userInfoShareResponse.getMobile() != null) {
                            aliUser.setAccount(userInfoShareResponse.getMobile());
                            aliUser.setAccountCheck(1);
                            String account = userInfoShareResponse.getMobile();
                            user = userServiceImpl.getByAccount(account);
                        }
                        aliUser.setHeadImg(userInfoShareResponse.getAvatar());
                        aliUser.setNickname(userInfoShareResponse.getNickName());
                        if (userInfoShareResponse.getGender() != null) {
                            if (userInfoShareResponse.getGender().equals("F")) {
                                aliUser.setSex(0);
                            } else if (userInfoShareResponse.getGender().equals("M")) {
                                aliUser.setSex(1);
                            } else {
                                aliUser.setSex(2);
                            }
                        } else {
                            aliUser.setSex(2);
                        }
                        redisCache.setCacheObject(thirdUserId, aliUser);
                    }
                }
            }else if(StringUtils.equals(ThirdUserTypeEnum.qq.name(),thirdUserTypeEnum.name())){
                thirdUserId = qqQuery(code);
            }
        } catch (WxErrorException e) {
            log.error("微信获取信息失败:{}",e.getMessage());
            throw new BusinessException("微信获取信息失败。");
        }catch (AlipayApiException e) {
            log.error("支付宝获取信息失败:{}",e.getMessage());
            throw new BusinessException("支付宝获取信息失败。");
        }

        UserThirdBind userThirdBind = userThirdBindServiceImpl.getByTypeAndValue(thirdUserTypeEnum.name(),thirdUserId);
        if(userThirdBind == null){
            if (user != null) {
                userThirdBind = userThirdBindServiceImpl.getByTypeAndUserId(user.getId(), thirdUserTypeEnum.name());
                if (userThirdBind == null) {
                    if (StringUtils.isEmpty(user.getHeadImg())) {
                        user.setHeadImg(userInfoShareResponse.getAvatar());
                    }
                    if (StringUtils.isEmpty(user.getNickname())) {
                        user.setNickname(userInfoShareResponse.getNickName());
                    }
                    if (userInfoShareResponse.getGender() != null) {
                        if (userInfoShareResponse.getGender().equals("F")) {
                            user.setSex(0);
                        } else if (userInfoShareResponse.getGender().equals("M")) {
                            user.setSex(1);
                        } else {
                            user.setSex(2);
                        }
                    } else {
                        user.setSex(2);
                    }
                    user.setAccountCheck(1);
                    userServiceImpl.update(user);
                    UserThirdBind temp = new UserThirdBind();
                    temp.setType(thirdUserTypeEnum.name());
                    temp.setValue(thirdUserId);
                    temp.setUserId(user.getId());
                    userThirdBindServiceImpl.insert(temp);
                } else {
                    user.setId(null);
                    user.setThirdUserId(thirdUserId);
                    user.setThirdUserType(thirdUserTypeEnum.name());
                    user.setOtherAli(true);
                    return user;
                }
            } else {
                user = new User();
                if (StringUtils.equals(ThirdUserTypeEnum.alipay.name(),thirdUserTypeEnum.name())) {
                    if (StringUtils.isEmpty(user.getHeadImg())) {
                        user.setHeadImg(userInfoShareResponse.getAvatar());
                    }
                    if (StringUtils.isEmpty(user.getNickname())) {
                        user.setNickname(userInfoShareResponse.getNickName());
                    }
                    if (userInfoShareResponse.getGender() != null) {
                        if (userInfoShareResponse.getGender().equals("F")) {
                            user.setSex(0);
                        } else if (userInfoShareResponse.getGender().equals("M")) {
                            user.setSex(1);
                        } else {
                            user.setSex(2);
                        }
                    } else {
                        user.setSex(2);
                    }
                    if (userInfoShareResponse.getMobile() != null) {
                        user.setAccount(userInfoShareResponse.getMobile());
                        user.setAccountCheck(1);
                    }
                    user.setRegisterTime(new Date());
                    user.setPassword(Md5Utils.hash("ej123456"));
                    userServiceImpl.insert(user);
                    UserThirdBind temp = new UserThirdBind();
                    temp.setType(thirdUserTypeEnum.name());
                    temp.setValue(thirdUserId);
                    temp.setUserId(user.getId());
                    userThirdBindServiceImpl.insert(temp);
                }
            }
            user.setThirdUserId(thirdUserId);
            user.setThirdUserType(thirdUserTypeEnum.name());
            return user;
        }else{
            User userById = userServiceImpl.selectUserById(userThirdBind.getUserId());
            if(userById == null){
                throw new BusinessException("用户查询失败。");
            }
            if (userInfoShareResponse != null) {
                if (StringUtils.isEmpty(userById.getHeadImg())) {
                    userById.setHeadImg(userInfoShareResponse.getAvatar());
                }
                if (StringUtils.isEmpty(userById.getNickname())) {
                    userById.setNickname(userInfoShareResponse.getNickName());
                }
                if (userById.getSex() == null || userById.getSex() == 0) {
                    if (userInfoShareResponse.getGender() != null) {
                        if (userInfoShareResponse.getGender().equals("F")) {
                            userById.setSex(0);
                        } else if (userInfoShareResponse.getGender().equals("M")) {
                            userById.setSex(1);
                        } else {
                            userById.setSex(2);
                        }
                    } else {
                        userById.setSex(2);
                    }
                }
                if (userInfoShareResponse.getMobile() != null && userById.getAccount().equals(userInfoShareResponse.getMobile())) {
                    userById.setAccountCheck(1);
                }
                userServiceImpl.update(userById);
            }
            if (StringUtils.equals(ThirdUserTypeEnum.wechat.name(),thirdUserTypeEnum.name())){
                if (StringUtils.isEmpty(userById.getHeadImg()) || StringUtils.isEmpty(userById.getNickname())) {
                    User wxUser = redisCache.getCacheObject(thirdUserId);
                    if (StringUtils.isEmpty(userById.getHeadImg())) {
                        userById.setHeadImg(wxUser.getHeadImg());
                    }
                    if (StringUtils.isEmpty(userById.getNickname())) {
                        userById.setNickname(wxUser.getNickname());
                    }
                    userServiceImpl.update(userById);
                }
            }
            userById.setThirdUserType(userThirdBind.getType());
            userById.setThirdUserId(userThirdBind.getValue());
            return userById;
        }
    }

    /**
     * 跳过绑定登录
     * @return
     */
    @Override
    public User skipBindLogin(String thirdUserId, String thirdUserType, String code)  {
        ThirdUserTypeEnum thirdUserTypeEnum = ThirdUserTypeEnum.valueOf(thirdUserType);
        if (thirdUserTypeEnum == null){
            throw new BusinessException("三方登录类型错误。");
        }

        UserThirdBind userThirdBind = userThirdBindServiceImpl.getByTypeAndValue(thirdUserType,thirdUserId);
        if(userThirdBind == null){
//           无三方绑定信息，无用户信息
            User user = new User();
            if (StringUtils.equals(ThirdUserTypeEnum.wechat.name(),thirdUserTypeEnum.name())){
                user = redisCache.getCacheObject(thirdUserId);
                log.info("----------------获得微信用户详情：{}",user);
                user.setAccount("");
                user.setAccountCheck(0);
            }else if(StringUtils.equals(ThirdUserTypeEnum.alipay.name(),thirdUserTypeEnum.name())){
                user = redisCache.getCacheObject(thirdUserId);
                user.setAccount("");
                user.setAccountCheck(0);
                log.info("----------------获得支付宝用户详情：{}",user);
            }else if(StringUtils.equals(ThirdUserTypeEnum.qq.name(),thirdUserTypeEnum.name())){
//                String access_token = this.getQQAccessToken(code);
//                String openid = this.qqQuery(access_token);
//                JSONObject jsonObject = this.getQQUserInfo(access_token,openid);
                user.setAccount("");
                user.setAccountCheck(0);
//                user.setNickname(jsonObject.getString("nickname"));
//                user.setHeadImg(jsonObject.getString("figureurl_qq_1"));
//                String gender = jsonObject.getString("gender");
//                if (gender.equals("女")) {
//                    user.setSex(2);
//                } else {
//                    user.setSex(1);
//                }
//                log.info("----------------获得QQ用户详情：{}", user);
            }else if(StringUtils.equals(ThirdUserTypeEnum.baidu.name(),thirdUserTypeEnum.name())){
//                String access_token = this.getBaiduAccessToken(code);
//                log.info("----------------获得百度用户详情：暂无");
                user.setAccount("");
                user.setAccountCheck(0);
            }

            user.setRegisterTime(new Date());
            user.setPassword(Md5Utils.hash("ej123456"));
            userServiceImpl.insert(user);
            UserThirdBind temp = new UserThirdBind();
            temp.setType(thirdUserTypeEnum.name());
            temp.setValue(thirdUserId);
            temp.setUserId(user.getId());
            userThirdBindServiceImpl.insert(temp);

            user.setThirdUserId(thirdUserId);
            user.setThirdUserType(thirdUserType);
            return user;
        } else {
            throw new BusinessException("存在三方绑定关系，无需跳过登录。");
        }
    }

    private String getBaiduAccessToken(String code) {
        String ur = String.format(BaiduConfig.ACCESS_TOKEN_URL, code, BaiduConfig.APPID, BaiduConfig.APPSECRET);
        String compile = "access_token=(\\w*)&";
        String result = this.getUrl(ur);
        return this.getMatcher(result,compile);
    }


    @Override
    public void qqNotify(String code, String deviceIdentify, String thirdUserId, Integer isMerge) {
        User user = thirdQuickLogin(code,ThirdUserTypeEnum.qq.name(), thirdUserId, isMerge);
        redisTemplate.opsForValue().set(deviceIdentify,JSONObject.toJSON(user));
    }

    @Override
    public User checkQQLogin(String deviceIdentify) {
        Object dto = redisTemplate.opsForValue().get(deviceIdentify);
        if(dto != null){
            return JSONObject.parseObject(dto.toString(),User.class);
        }
        return null;
    }


    @Override
    public User checkThirdUserIdIsBindAccount(String thirdType, String thirdUserId) {
        UserThirdBind userThirdBind = userThirdBindServiceImpl.getByTypeAndValue(thirdType,thirdUserId);
        User user = null;
        if(userThirdBind == null){
            user = new User();
            user.setThirdUserId(thirdUserId);
            user.setThirdUserType(thirdType);
        }else{
            user = userServiceImpl.selectUserById(userThirdBind.getUserId());
            if(user == null){
                throw new BusinessException("用户查询失败。");
            }
            user.setThirdUserType(userThirdBind.getType());
            user.setThirdUserId(userThirdBind.getValue());
        }
        return user;
    }

    @Override
    public void loginLimitCheck(User userOld){
        Product product = productServiceImpl.getByPackageKey(DeviceContext.getProductPackageKey());
        if (product != null && product.getLoginLimit() != null && product.getLoginLimit() > 0) {
            LinkedHashMap<String, String> userMap = redisCache.getCacheObject(userOld.getUserIdentify() + "_" + DeviceContext.getProductPackageKey());
            if (userMap != null && userMap.size() > 0) {
                LinkedHashMap<String, String> newUserMap = new LinkedHashMap<>(product.getLoginLimit());
                if (!userMap.containsKey(DeviceContext.getDeviceIdentify())) {
                    for (String key : userMap.keySet()) {
                        try {
                            JwtUtils.verify(userOld.getId().toString(), userOld.getPassword(),userMap.get(key));
                            newUserMap.put(DeviceContext.getDeviceIdentify(), userMap.get(key));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (newUserMap.size() >= product.getLoginLimit()) {
                        throw new BusinessException("您的账号登录的设备数量已达上限，登录失败。", 1001);
                    }
                } else {
                    newUserMap.putAll(userMap);
                }
                redisCache.setCacheObject(userOld.getUserIdentify() + "_" + DeviceContext.getProductPackageKey(), newUserMap);
            }
        }
    }

    @Override
    public void limitLogin(ThirdLoginDto dto, User user, Integer isForce) {
        Product product = productServiceImpl.getByPackageKey(DeviceContext.getProductPackageKey());
        if (product != null && product.getLoginLimit() != null && product.getLoginLimit() > 0) {
            LinkedHashMap<String, String> userMap = redisCache.getCacheObject(user.getUserIdentify() + "_" + DeviceContext.getProductPackageKey());
            if (userMap != null && userMap.size() > 0) {
                LinkedHashMap<String, String> newUserMap = new LinkedHashMap<>();
                if (!userMap.containsKey(DeviceContext.getDeviceIdentify())) {
                    for (String userKey : userMap.keySet()) {
                        try {
                            if (redisCache.hasKey(userMap.get(userKey))) {
                                newUserMap.put(userKey, userMap.get(userKey));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (newUserMap.size() >= product.getLoginLimit()) {
                        if (isForce == 0) {
                            throw new BusinessException("您的账号登录的设备数量已达上限，登录失败。", 1001);
                        } else {
                            LinkedHashMap<String, String> tempMap = new LinkedHashMap<>();
                            ListIterator<Map.Entry<String,String>> i = new ArrayList<>(newUserMap.entrySet()).listIterator(newUserMap.size());
                            int index = 1;
                            while(i.hasPrevious()) {
                                if (index > product.getLoginLimit() - 1) {
                                    break;
                                }
                                Map.Entry<String, String> entry=i.previous();
                                System.out.println(entry.getKey()+":"+entry.getValue());
                                tempMap.put(entry.getKey(), entry.getValue());
                                index ++;
                            }
                            newUserMap = tempMap;
                        }
                    }
                } else {
                    newUserMap.putAll(userMap);
                }
                redisCache.setCacheObject(user.getUserIdentify() + "_" + DeviceContext.getProductPackageKey(), newUserMap);
            }
        }
        dto.setToken(JwtUtils.createToken(user.getId().toString(),user.getPassword(), JwtUtils.EXPIRE_TIME_SIXTY));

        List<String> oldToken = redisCache.getCacheObject(user.getUserIdentify() + "oldToken");
        if (oldToken == null) {
            oldToken = new ArrayList<>();
        } else {
            if (oldToken.size() > 20) {
                oldToken = oldToken.subList(oldToken.size() - 10, oldToken.size() -1);
            }
        }
        oldToken.add(dto.getToken());
        redisCache.setCacheObject(user.getUserIdentify() + "oldToken", oldToken);

        LinkedHashMap<String, String> userMap = redisCache.getCacheObject(user.getUserIdentify() + "_" + DeviceContext.getProductPackageKey());
        if (userMap == null) {
            userMap = new LinkedHashMap<>();
        }
        userMap.put(DeviceContext.getDeviceIdentify(), dto.getToken());
        redisCache.setCacheObject(user.getUserIdentify() + "_" + DeviceContext.getProductPackageKey(), userMap);

        redisCache.setCacheObject(dto.getToken(), DeviceContext.getDeviceIdentify() + "_" + DeviceContext.getProductPackageKey(), 60, TimeUnit.DAYS);

    }

    /**
     * 微信查询用户信息
     * @param code
     * @return
     * @throws WxErrorException
     */
    private WxOAuth2UserInfo wxQuery(String code) throws WxErrorException{

        WxOAuth2AccessToken wxOAuth2AccessToken = this.getAccessToken(code);
        if (wxOAuth2AccessToken == null){
            throw new BusinessException("accessToken获取失败");
        }
        WxOAuth2UserInfo wxOAuth2UserInfo = this.getUserInfo(wxOAuth2AccessToken);
        if(wxOAuth2UserInfo == null){
            throw new BusinessException("用户信息获取失败");
        }
        User wxUser = new User();
        wxUser.setNickname(wxOAuth2UserInfo.getNickname());
        wxUser.setHeadImg(wxOAuth2UserInfo.getHeadImgUrl());
        redisCache.setCacheObject(wxOAuth2UserInfo.getUnionId(), wxUser);
        log.info("----------------获得微信用户详情：{}",wxOAuth2UserInfo);
        //用户授权成功
        log.info("成功");
        return wxOAuth2UserInfo;
    }



    /**
     * 支付宝查询用户数据
     * @param code
     * @return
     * @throws AlipayApiException
     */
    private JSONObject aliQuery(String code) throws AlipayApiException {
        JSONObject resultJson = new JSONObject();
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(code);
        request.setGrantType("authorization_code");
        AlipaySystemOauthTokenResponse response = alipayPayServiceImpl.getAliPayService().execute(request);
        if(response.isSuccess()){
            String body = response.getBody();
            if(!StringUtils.isEmpty(body)){
                JSONObject jsonObject = JSONObject.parseObject(body);
                JSONObject object = jsonObject.getJSONObject("alipay_system_oauth_token_response");
                resultJson.put("userId",object.getString("user_id"));
                resultJson.put("accessToken",object.getString("access_token"));
                return resultJson;
            }
        } else {
            log.error("支付宝获取用户信息查询失败");
        }

        return null;
    }

    private AlipayUserInfoShareResponse getUserInfo(String accessToken, int number) throws AlipayApiException {
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayPayServiceImpl.getAliPayService().execute(request,accessToken);
        if(response.isSuccess()){
            log.info("----------------获得支付宝用户详情：{}",response.getBody());
            //用户授权成功
            log.info("成功");
            return response;
        } else {
            log.info("***********失败，自旋开始第：{}次",number);
            number += 1;
            if(number < 3){
                log.info("调用用户详情失败，尝试：*******{}*******",number);
                return this.getUserInfo(accessToken,number);
            }
            log.error("支付宝获取用户信息查询失败: {}", response);
        }
        return null;
    }



    /**
     * 查询用户信息
     * @param code
     * @return
     */
    public String qqQuery(String code) {
        //Step2：通过Authorization Code获取Access Token
        String access_token = this.getQQAccessToken(code);

        //Step3: 获取回调后的 openid 值
        String openid = this.getQQOpenId(access_token);

        //Step4：获取QQ用户信息
        // JsonObject jsonObject = this.getQQUserInfo(access_token,openid);

        return openid;
    }



    /**
     * 获取Access Token值
     */
    private String getQQAccessToken(String code){
        String ur = String.format(QQConfig.ACCESS_TOKEN_URL, QQConfig.APPID, QQConfig.APPSECRET,code, QQConfig.REDIRECT_URI);
        String compile = "access_token=(\\w*)&";
        String result = this.getUrl(ur);
        return this.getMatcher(result,compile);
    }

    /**
     * 获取openId
     * @param accessToken
     * @return
     */
    private String getQQOpenId(String accessToken) {
        String url = String.format(QQConfig.OPEN_ID_URL, accessToken);
        String compile = "openid\":\"(\\w*)\"";
        String result = this.getUrl(url);
        return this.getMatcher(result,compile);
    }

    /**
     * 获取qq用户信息
     * @param accessToken
     * @param openId
     * @return
     */
    private JSONObject getQQUserInfo(String accessToken, String openId) {
        String url = String.format(QQConfig.USER_INFO_URL, accessToken, QQConfig.APPID, openId);
        String result = this.getUrl(url);
        return JSON.parseObject(result);
    }

    private String getMatcher(String result,String compile) {
        //使用正则表达式解析网址
        Pattern p = Pattern.compile(compile);
        Matcher m = p.matcher(result);
        m.find();
        return m.group(1);
    }

    //解析url
    private String getUrl(String url) {
        return restTemplate.getForObject(url,String.class);
    }




}
